Gatsby is a static web site framework that’s based on React.
We can use it to create static websites from external data sources and more.
In this article, we’ll look at how to create a site with Gatsby.
Adding Markdown Pages
We can add pages from Markdown by adding the gatsby-transformer-remark and gatsby-source-filesystem plugins.
To do this, we write:
gatsby-config.js
module.exports = {
plugins: [
`gatsby-transformer-remark`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `content`,
path: `${__dirname}/src/content`,
},
},
],
}
gatsby-node.js
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions
const blogPostTemplate = require.resolve(`./src/templates/post.js`)
const result = await graphql(`
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
limit: 1000
) {
edges {
node {
frontmatter {
slug
}
}
}
}
}
`)
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`)
return
}
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.frontmatter.slug,
component: blogPostTemplate,
context: {
slug: node.frontmatter.slug,
},
})
})
}
src/templates/post.js
import React from "react" { graphql } from "gatsby"
export default function Template({
data,
}) {
const { markdownRemark } = data
const { frontmatter, html } = markdownRemark
return (
<div className="blog-post-container">
<div className="blog-post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
</div>
)
}
export const pageQuery = graphql`
query($slug: String!) {
markdownRemark(frontmatter: { slug: { eq: $slug } }) {
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
slug
title
}
}
}
`
src/content/post.md
---
title: My First Post
date: 2019-07-10
slug: /my-first-post
---
This is my first Gatsby post written in Markdown!
We add the gatsby-source-filesystem plugin to read the Markdown files from the src/content folder.
And we add the gatsby-transformer-remark plugin to transform the Markdown files to HTML.
Then in gatsby-node.js , we get the Markdown content with the allMarkdownRemark query.
We sort the entries by date with the sort values.
And we limit the number of entries to 1000.
And we specify that we return the slug in the result.
Then we call forEach to call the createPage function to create the pages.
The path is the URL path to access the page.
component has the template file path.
And context has the data that we want to display from the result entry.
In post.js , we have the query to get a single entry.
We get the entry with give slug with the markdownRemark query.
Then we get the html field to get the content.
frontmatter has the metadata for the page.
And we get that from the data prop’s markdownRemark property.
Finally, we render that in the JSX of Template .
Now we should see the post.md content displayed.
Add a List of Markdown Blog Posts
We can also add a page withn multiple posts.
To do this, we write:
src/page/index.js
import React from "react"
import { graphql } from "gatsby"
import { Link } from "gatsby"
const PostLink = ({ post }) => (
<div>
<Link to={post.frontmatter.slug}>
{post.frontmatter.title} ({post.frontmatter.date})
</Link>
</div>
)
const IndexPage = ({
data: {
allMarkdownRemark: { edges },
},
}) => {
const Posts = edges
.filter(edge => !!edge.node.frontmatter.date)
.map(edge => <PostLink key={edge.node.id} post={edge.node} />)
return <div>{Posts}</div>
}
export default IndexPage
export const pageQuery = graphql`
query {
allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
edges {
node {
id
excerpt(pruneLength: 250)
frontmatter {
date(formatString: "MMMM DD, YYYY")
slug
title
}
}
}
}
}
`
We create the PostLink component to display a link for the post.
IndexPage has the posts.
We get the posts data from the data prop’s allMarkdownRemark.edges property.
And we map the entries to the PostLink component to render each entry with the PostLink component.
The pageQuery gets us the data for the data prop.
Conclusion
We can render one or more Markdown files in our Gatsby project.